<template>
  <div ref="ele" class="double-view" v-show="show">
      
  </div>
</template>

<script>
/* eslint-disable */
import echarts from "echarts";
import Debug from "debug";
import _ from "lodash";
import color from "color";
const dbg = Debug("DoubleView.vue");
dbg.enabled = true;

export default {
  data() {
    return {
      chart: echarts.init(document.createElement("null")),
      channel: ["", ""]
    };
  },
  props: {
    showindex: {
      type: Number,
      default: 3
    },
    trendData: {
      type: Object
    },
    testIdLines: {
      type: Object
    },
    raw: {
      type: Object
    },
    channel2GoodText: {
      type: Function
    },
    channel2danwei: {
      type: Function
    },
    count_in_selection: {
      type: Number
    }
  },
  computed: {
    show() {
      return this.showindex === 1;
    },
    /**@return {Object}
     */
    abnormal_type2color() {
      return this.$store.state.abnormal_type2color;
    },
    channel2max() {
      return this.$store.state.feature_channel_2_max;
    },
    abnormal_type2comment() {
      return this.$store.getters["abnormal_type2comment"];
    },
    gray_colors() {
      return this.$store.state["gray_colors"];
    },
    font_size() {
      return this.$store.getters["axis_font_size"];
    },
    channel2yAxisName() {
      return this.$store.state["channel2yAxisName"];
    },
    colorByType() {
      return type => this.abnormal_type2color[this.abnormal_type2comment[type]];
    },
    colorChangeLightness() {
      return (hexColor, L) => {
        let c = color(hexColor);
        // debugger;
        let hslc = c.hsl();
        hslc = hslc.lightness(L);
        // debugger
        return hslc.hex();
      };
    },
    OFFSETS() {
      let trendData = this.trendData;
      return _.map(this.channel, channel => {
        if (!channel) return 0;
        let mapped = _.filter(
          _.map(trendData, e => (e ? (e[channel] ? e[channel] : null) : null))
        );
        if (mapped.length == 0) return 0;
        let mapped_mins = mapped.map(e => e["min"]);
        let min_value = _.min(_.flatten(mapped_mins));

        if (min_value < 0) {
          return Math.ceil(0 - min_value);
        } else {
          return 0;
        }
      });
    },
    opt_yAxises() {
      return _.map(this.channel, (chan, chan_index) => {
        return {
          gridIndex: chan_index,
          axisLabel: {
            formatter: value => {
              if (this.OFFSETS && this.OFFSETS[chan_index]) {
                return value - this.OFFSETS[chan_index];
              } else {
                return value;
              }
            },
            color: this.gray_colors[1],
            fontSize: this.font_size + 1
          },
          axisLine: {
            lineStyle: {
              color: this.gray_colors[0]
            }
          },
          min: 0 + this.OFFSETS[chan_index],
          // max: this.channel2max[chan] + this.OFFSETS[chan_index],
          name: this.channel2GoodText(this.channel[chan_index]),
          nameGap: 40,
          nameRotate: 90,
          nameLocation: "center",
          nameTextStyle: {
            color: this.gray_colors[1],
            fontSize: this.font_size + 1
          },
          splitArea: {
            show: false
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: this.gray_colors[0],
              type: "dotted",
              opacity: 0.5
            }
          }
        };
      });
    },
    opt_trend_serieses() {
      return _.flatten(
        this.channel.map((chan, chan_index) => {
          let mapValues_ed = _.mapValues(this.trendData, (channels, type) => {
            if (!channels) return null;
            let channel = this.channel[chan_index]; /**@todo */
            let channel_data = channels[channel];
            if (!channel_data) return null;
            if (!channel_data.data) return null;
            let data = channel_data.data.map(
              row => row.map(d => d + this.OFFSETS[chan_index]) /**@todo */
            );
            return [
              {
                //min
                name: `${this.abnormal_type2comment[type]}`,
                type: "line",
                data: channel_data.index.map((d, i) => {
                  return [d, data[i][0].toFixed(2)];
                }),
                itemStyle: {
                  color: this.colorByType(type)
                },
                lineStyle: {
                  normal: {
                    color: this.colorByType(type),
                    opacity: 0.1,
                    type: "dotted"
                  }
                },
                stack: `bound(${type}-${chan_index})`,
                smooth: true
                // symbolSize: 0
              },
              {
                // 25%
                name: `${this.abnormal_type2comment[type]}`,
                type: "line",
                data: channel_data["index"].map((d, i) => {
                  return [d, data[i][1].toFixed(2)];
                }),
                itemStyle: {
                  color: this.colorByType(type)
                },
                lineStyle: {
                  normal: {
                    color: this.colorByType(type),
                    opacity: 0
                  }
                },
                stack: `main(${type}-${chan_index})`,
                smooth: true
              },
              {
                // 50%
                name: `${this.abnormal_type2comment[type]}`,
                type: "line",
                data: channel_data["index"].map((d, i) => {
                  return [d, data[i][2].toFixed(2)];
                }),
                itemStyle: {
                  color: this.colorByType(type)
                },
                lineStyle: {
                  color: this.colorChangeLightness(this.colorByType(type), 45),
                  opacity: 0.5
                },
                smooth: true
              },
              {
                //75%
                name: `${this.abnormal_type2comment[type]}`,
                type: "line",
                data: channel_data["index"].map((d, i) => {
                  return [d, (data[i][3] - data[i][1]).toFixed(2)];
                }),
                lineStyle: {
                  normal: {
                    color: this.colorByType(type),
                    opacity: 0
                  }
                },
                itemStyle: {
                  color: this.colorByType(type)
                },
                areaStyle: {
                  color: this.colorChangeLightness(this.colorByType(type), 65),
                  opacity: 0.4
                },
                stack: `main(${type}-${chan_index})`,
                smooth: true
              },
              {
                //max
                name: `${this.abnormal_type2comment[type]}`,
                type: "line",
                data: channel_data.index.map((d, i) => {
                  return [d, (data[i][4] - data[i][0]).toFixed(2)];
                }),
                itemStyle: {
                  color: this.colorByType(type)
                },
                lineStyle: {
                  normal: {
                    color: this.colorByType(type),
                    opacity: 0.1,
                    type: "dotted"
                  }
                },
                areaStyle: {
                  color: this.colorChangeLightness(this.colorByType(type), 90),
                  opacity: 0.5
                },
                stack: `bound(${type}-${chan_index})`,
                smooth: true
              }
            ].map(e => {
              e.yAxisIndex = chan_index; /**@todo */
              e.xAxisIndex = chan_index;
              e = {
                ...e,
                symbol: "none",
                showSymbol: false
              };
              return e;
            });
          });

          mapValues_ed = _.map(mapValues_ed, (val, key) => {
            return { val, key };
          });
          mapValues_ed = mapValues_ed.sort((A, B) => {
            if (A && B) {
              let [nameA, nameB] = [
                this.abnormal_type2comment[A["key"]],
                this.abnormal_type2comment[B["key"]]
              ].map(e => e + "");
              let [AisTypical, BisTypical] = [nameA, nameB].map(e =>
                e.startsWith("C")
              );
              // debugger
              if (AisTypical && BisTypical) return nameA.localeCompare(nameB);
              if (AisTypical && !BisTypical) return -1;
              if (!AisTypical && BisTypical) return 1;
              return nameA.localeCompare(nameB);
            }
            return A - B;
          });
          mapValues_ed = mapValues_ed.map(e => e["val"]);
          return _.filter(_.flatten(_.map(mapValues_ed)));
        })
      );
    },
    opt_line_serieses() {
      let arr = [];
      this.channel.map((channel, chan_index) => {
        for (let testid in this.testIdLines) {
          let data_parent = this.testIdLines[testid]["channel_data"].find(
            e => e["channel"] == channel
          );
          if (data_parent) {
            let data = data_parent["data"].map((e, i) => [
              i,
              e + this.OFFSETS[chan_index]
            ]);
            arr.push({
              type: "line",
              name: `line`,
              data: data,
              lineStyle: {
                type: "solid",
                color: "#ff80ff",
                opacity: 0.6
              },
              itemStyle: {
                color: "#ff80ff"
              },
              markPoint: {
                data: [
                  {
                    value: `${testid}`,
                    coord: _.maxBy(data, d => d[1])
                  }
                ],
                label: {
                  fontSize: 10
                },
                itemStyle: {
                  color: "rgba(255,0,0,0.3)"
                }
              },
              xAxisIndex: chan_index,
              yAxisIndex: chan_index
            });
          }
        }
      });

      return arr;
    },
    opt_text_graphic() {
      return _.map(this.opt_grids, (g, index) => {
        return {
          type: "text",
          right: 100,
          style: {
            text: this.channel2GoodText(this.channel[index]),
            font: `bolder 2.5em "Microsoft YaHei", sans-serif`,
            fill: "#e2e2e2"
          },
          cursor: "default"
        };
      }).map((e, i) => {
        if (i == 0) {
          e = {
            ...e,
            top: 45
          };
        } else {
          e = {
            ...e,
            top: 380
          };
        }

        return e;
      });
    },
    opt_fake_raw() {
      if (this.opt_trend_serieses.length) {
        return [
          {
            type: "line",
            name: "date"
          }
        ];
      } else {
        return [];
      }
    },
    opt_grids: () =>
      [
        { left: 70, top: 45, right: 100 },
        { left: 70, bottom: 60, right: 100 }
      ].map(e => {
        e = {
          ...e,
          show: false,
          height: "37.5%"
        };
        return e;
      }),
    opt_echarts() {
      let vue = this;
      return {
        backgroundColor: "white",
        grid: this.opt_grids,
        legend: {
          data: [
            ...this.opt_trend_serieses.map(e => {
              return {
                name: e["name"],
                icon:
                  "path://M 0 0.15 L 1 0.15 L 1 0.85  L 0 0.85 L 0 0 z M 0 0.4 L -0.3 0.4 L -0.3 0.6 L 0 0.6 z M 1 0.4 L 1.3 0.4 L 1.3 0.6 L 1 0.6 z "
              };
            }),
            "line",
            { name: "date", icon: "none" }
          ],
          top: 10,
          itemWidth: 30,
          itemHeight: 14,
          left: "center",
          formatter: function(name) {
            if (name == "date") {
              if (!vue.raw.dates.length) return "";
              return `[${vue.raw.dates[0]} ~ ${
                vue.raw.dates[vue.raw.dates.length - 1]
              } , ${vue.$_getCountInSelection()} tests]`;
            } else {
              if (name.startsWith("C")) {
                name = name.replace("C", "T");
              }
              return name;
            }
          }
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            // type: "cross"
          },
          formatter: function(params) {
            let findTypeidByTypenametext = str => {
              for (let id in vue.abnormal_type2comment) {
                if (vue.abnormal_type2comment[id] == str) {
                  return id;
                }
              }
              return null;
            };
            if (params.length) {
              let uniq_params = _.uniqBy(params, e => e["seriesName"]);
              let channel_index = params[0]["axisIndex"];
              // debugger
              let channel = vue.channel[channel_index];
              if (!channel) {
                return;
              }
              let texts = uniq_params
                .map(param => {
                  let tune = param["data"][0];
                  let dataIndex = param["dataIndex"];
                  let typename = param["seriesName"];
                  let typeid = findTypeidByTypenametext(typename);
                  if (!typeid) {
                    return "";
                  }
                  try {
                    let [min, q1, q2, q3, max] = [
                      vue.trendData[typeid][channel]["data"][dataIndex][0],
                      vue.trendData[typeid][channel]["data"][dataIndex][1],
                      vue.trendData[typeid][channel]["data"][dataIndex][2],
                      vue.trendData[typeid][channel]["data"][dataIndex][3],
                      vue.trendData[typeid][channel]["data"][dataIndex][4]
                    ].map(e => {
                      // let s = String(e);
                      // let i = s.indexOf(".");
                      /**@description 精确到小数点后三位 */
                      return Math.round(e * 1000) / 1000;
                    });

                    /**@description 记得把C1C2改成T1T2 */
                    if (typename.startsWith("C")) {
                      typename = typename.replace("C", "T");
                    }

                    return `Mode : ${typename}<br> Tune : ${tune} ms<br>
                    max : ${max}  ${vue.channel2danwei(channel)}<br>
                    q3 : ${q3}  ${vue.channel2danwei(channel)}<br>
                    q2 : ${q2}  ${vue.channel2danwei(channel)}<br>
                    q1 : ${q1}  ${vue.channel2danwei(channel)}<br>
                    min : ${min}  ${vue.channel2danwei(channel)}<br> 
                  `;
                  } catch (e) {
                    return "";
                  }
                })
                .filter(e => !!e);
              return `Channel : ${vue.channel2GoodText(
                channel
              )} <br>${texts.join("<br>")}`;
            }
          }
        },
        xAxis: [
          {
            type: "category",
            data: _.range(0, 2001),
            gridIndex: 0
          },
          {
            type: "category",
            data: _.range(0, 2001),
            gridIndex: 1
          }
        ].map(e => {
          e = {
            ...e,
            axisLine: {
              onZero: false,
              lineStyle: {
                fontSize: 12,
                color: this.gray_colors[0]
              }
            },
            name: "Tune (ms)",
            nameGap: 34,
            nameLocation: "center",
            nameTextStyle: {
              color: this.gray_colors[1],
              textShadowColor: "transparent",
              textShadowBlur: 0,
              textShadowOffsetY: 14,
              fontSize: this.font_size + 1
            },
            axisLabel: {
              color: this.gray_colors[1],
              fontSize: this.font_size + 1,
              interval: (index, value) => {
                return value % 250 == 0;
              }
            },
            axisTick: {
              alignWithLabel: true,
              interval: (index, value) => {
                return value % 250 == 0;
              }
            }
          };
          return e;
        }),
        yAxis: this.opt_yAxises,
        graphic: this.opt_text_graphic,
        series: this.opt_trend_serieses
          .concat(this.opt_line_serieses)
          .concat(this.opt_fake_raw)
      };
    },
    show() {
      return this.showindex === 1;
    }
  },
  mounted() {
    this.chart = echarts.init(this.$refs["ele"]);
    this.$_draw();
  },
  methods: {
    $_draw() {
      this.chart.clear();
      this.chart.setOption(this.opt_echarts);
    },
    /**@param {("speed"|"i50"|"i30"|"u30"|"u45"|"u50")[]} channels
     @api public*/
    setChannels(channels) {
      this.channel = channels;
    },
    $_getCountInSelection() {
      return this.count_in_selection;
    }
  },
  watch: {
    opt_echarts() {
      // if (this.show) {
      this.$_draw();
      // }
    },
    show(val) {
      if (val) {
        // this.$_draw();
      }
    }
  }
};
</script>

<style lang="less">
.double-view {
  background-color: white;
  width: 1326px;
  height: 708px;
}
</style>
